<?php

/***************************************************************************
 *
 * Copyright (c) 2012 Baidu.com, Inc. All Rights Reserved
 *
 **************************************************************************/

require_once(dirname(__FILE__) . '/BaiduUtils.php');

/**
 * Client for Baidu OAuth2.0 service.
 * 
 * @package Baidu
 * @author zhujianting(zhujianting@baidu.com)
 * @version v2.0.0
 */
class BaiduOAuth2
{
    /**
     * Endpoints for Baidu OAuth2.0.
     */
    public static $BD_OAUTH2_ENDPOINTS = array(
        'authorize'    => 'https://openapi.baidu.com/oauth/2.0/authorize',
        'token'        => 'https://openapi.baidu.com/oauth/2.0/token',
        'logout'    => 'https://openapi.baidu.com/connect/2.0/logout',
    );
  
    protected $clientId;
    protected $clientSecret;
    protected $redirectUri;
    
    /**
     * Constructor
     * 
     * @param string $clientId Client_id of the baidu thirdparty app or access_key of the developer.
     * @param string $clientSecret Client_secret of the baidu thirdparty app or secret_key of the developer.
     */
    public function __construct($clientId, $clientSecret)
    {
        $this->clientId = $clientId;
        $this->clientSecret = $clientSecret;
    }
    
    /**
     * Set the redirect uri for the app.
     * 
     * @param $redirectUri Where to redirect after user authorization.
     * @return BaiduOAuth2
     */
    public function setRedirectUri($redirectUri)
    {
        if (empty($redirectUri)) {
            $redirectUri = BaiduUtils::getCurrentUrl();
        }
        $this->redirectUri = $redirectUri;
        return $this;
    }
    
    /**
     * Get the redirect uri for the app.
     * 
     * @return string
     */
    public function getRedirectUri()
    {
        return $this->redirectUri;
    }
    
    /**
     * Get a Logout URL suitable for use with redirects.
     * 
     * @param string $accessToken Access token for current user
     * @param string $next Url to go to after a successful logout
     * @return String The URL for the logout flow
     */
    public function getLogoutUrl($accessToken, $next = '')
    {
        $params = array('access_token' => $accessToken,
                        'next' => $next ? $next : BaiduUtils::getCurrentUrl());
        return self::$BD_OAUTH2_ENDPOINTS['logout'] . '?' . http_build_query($params, '', '&');
    }
    
    /**
     * Get baidu oauth2's authorization granting url.
     * 
     * @param string $responseType	Response type, 'code' or 'token'
     * @param string $scope		blank space separated list of requested extended perms
     * @param string $display	Authorization page style, 'page', 'popup', 'touch' or 'mobile'
     * @param string $state		state parameter
     * @return string Page url for authorization granting
     */
    public function getAuthorizeUrl($responseType = 'code', $scope = '', $state = '', $display = 'popup')
    {
        $params = array(
            'client_id'        => $this->clientId,
            'response_type'    => $responseType,
            'redirect_uri'    => $this->redirectUri,
            'scope'            => $scope,
            'state'            => $state,
            'display'        => $display,
        );
        return self::$BD_OAUTH2_ENDPOINTS['authorize'] . '?' . http_build_query($params, '', '&');
    }
    
    /**
     * Get access token ifno by authorization code.
     * 
     * @param string $code	Authorization code
     * @return array|false returns access token info if success, or false if failed
     */
    public function getAccessTokenByAuthorizationCode($code)
    {
        $params = array(
            'grant_type'    => 'authorization_code',
            'code'            => $code,
            'client_id'        => $this->clientId,
            'client_secret'    => $this->clientSecret,
            'redirect_uri'    => $this->redirectUri,
        );
        return $this->makeAccessTokenRequest($params);
    }
    
    /**
     * Get access token info by client credentials.
     * 
     * @param string $scope		Extend permissions delimited by blank space
     * @return array|false returns access token info if success, or false if failed.
     */
    public function getAccessTokenByClientCredentials($scope = '')
    {
        $params = array(
            'grant_type'    => 'client_credentials',
            'client_id'        => $this->clientId,
            'client_secret'    => $this->clientSecret,
            'scope'            => $scope,
        );
        return $this->makeAccessTokenRequest($params);
    }
    
    /**
     * Get access token info by developer credentials
     * @param string $accessKey	Access key you got from baidu cloud platform
     * @param string $secretKey	Secret key you got from baidu cloud platform
     * @return array|false Returns access token info if success, or false if failed
     */
    public function getAccessTokenByDeveloperCredentials($accessKey, $secretKey)
    {
        $params = array(
            'grant_type'    => 'developer_credentials',
            'client_id'        => $accessKey,
            'client_secret'    => $secretKey,
        );
        return $this->makeAccessTokenRequest($params);
    }
    
    /**
     * Refresh access token by refresh token.
     * 
     * @param string $refreshToken The refresh token
     * @param string $scope	Extend permissions delimited by blank space
     * @return array|false returns access token info if success, or false if failed.
     */
    public function getAccessTokenByRefreshToken($refreshToken, $scope = '')
    {
        $params = array(
            'grant_type'    => 'refresh_token',
            'refresh_token'    => $refreshToken,
            'client_id'        => $this->clientId,
            'client_secret'    => $this->clientSecret,
            'scope'            => $scope,
        );
        return $this->makeAccessTokenRequest($params);
    }
    
    /**
     * Make an oauth access token request
     * 
     * The parameters:
     * - client_id: The client identifier, just use api key
     * - response_type: 'token' or 'code'
     * - redirect_uri: the url to go to after a successful login
     * - scope: The scope of the access request expressed as a list of space-delimited, case sensitive strings.
     * - state: An opaque value used by the client to maintain state between the request and callback.
     * - display: login page style, 'page', 'popup', 'touch' or 'mobile'
     * 
     * @param array $params	oauth request parameters
     * @return mixed returns access token info if success, or false if failed
     */
    public function makeAccessTokenRequest($params)
    {
        $result = BaiduUtils::request(self::$BD_OAUTH2_ENDPOINTS['token'], $params, 'POST');
        if ($result) {
            $result = json_decode($result, true);
            if (isset($result['error_description'])) {
                BaiduUtils::setError($result['error'], $result['error_description']);
                return false;
            }
            return $result;
        }
        
        return false;
    }
}

 
/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */
